@node Bootstrap
@chapter Bootstrap

The process of executing the various tools required to bring all the
generated files up to date in a directory freshly checked out from
source control can be quite involved.  Many GNU projects use a
@command{bootstrap} script to execute some or all of the following in the
correct order: @command{gnulib-tool}, @command{autopoint},
@command{libtoolize}, @command{autoreconf}. Often there's also
additional file-processing and assorted book-keeping that also falls
under the control of @command{bootstrap}, but it's wasteful for the
maintainers of all these projects to manually reinvent a custom script
on a case-by-case basis.

Gnulib is designed to provide a central library of exemplar
implementations to promote the sharing of useful common code among
GNU project maintainers. However, the bootstrapping needs of these
projects vary enormously, so Gnulib's @command{bootstrap} needs to be
extremely @strong{customisable} and extensible, with less effort than
would be otherwise required to invent an ad-hoc solution.
Unfortunately, Gnulib's @command{bootstrap} is not at all extensible,
and makes it very hard to customize for any additional book-keeping or
other tasks required at bootstrap-time.  This version of
@command{bootstrap} does not have any of those short-comings -- in
addition to the basic bootstrapping facilities provided by Gnulib's
implementation, this version can be changed and upgraded on the fly by
overridding or appending to existing functions in @file{bootstrap.conf}.


@menu
* Customisation::
* Usage Patterns::
* Known Bugs::
@end menu


@node Customisation
@section Customisation

There are four distinct ways to customize the functionality of
@command{bootstrap}, all requiring creation of a @file{bootstrap.conf}
file in the same directory as the imported @command{bootstrap} script
itself.

@menu
* Configuration Variables::
* Require Variables::
* Hook Functions::
* Function Replacement::
@end menu


@node Configuration Variables
@subsection Configuration Variables

For all but the more complex customisations, you need only change
the value of a selection of the following shell variables in
@file{bootstrap.conf}, to reflect whatever is appropriate to your
package.

@example
    vc_ignore=.gitignore
@end example

@table @code

@cnindex buildreq
@item buildreq
A newline-delimited list of triples of @strong{programs} (which must
accept the option @option{--version} without hanging or failing), the
@strong{minimum version required} (or just `-' in the version field if
any version will be sufficient) and @strong{homepage URL (to
help users locate missing packages)

@smallexample
buildreq='
        git        1.5.5   http://git-scm.com
        help2man   1.29    http://www.gnu.org/s/help2man
'
@end smallexample

If you specify a minimum version of Autoconf with @code{AC_PREREQ},
that version will be checked automatically without needing to be
listed in @code{buildreq}.  Similarly for a minimum Automake version
declared with @code{AM_INIT_AUTOMAKE}, Libtool version with
@code{LT_PREREQ}, or Autopoint version with @code{AM_GNU_GETTEXT_VERSION}.

If @code{AB_INIT} is declared in @file{configure.ac}, then a versionless
requirement for Autobuild is added automatically, and finally if there
are any diff files under @code{local_gl_path}, then a versionless
requirement for patch is also added.

When @command{bootstrap} is invoked, it will check that all the listed
and automatically added tools are available at the given minimum version,
or else bail out with a diagnostic.


@cnindex buildreq_readme
@item buildreq_readme
Name of a file containing instructions on installing missing packages
required in @code{buildreq}. Usually, the instructions at the given
URL should be sufficient, though some projects add additional notes
in @file{HACKING}.

@smallexample
buildreq_readme=README-hacking
@end smallexample


@cnindex build_aux
@item build_aux
This is automatically extracted from the @code{AC_CONFIG_AUX_DIR}
declaration in @file{configure.ac}, though you can specify it in
@file{bootstrap.conf} if you don't otherwise want to declare
@code{AC_CONFIG_AUX_DIR} in @file{configure.ac}.

@cnindex macro_dir
@item macro_dir
This is automatically extracted from @file{configure.ac}, or if
neither @code{AC_CONFIG_MACRO_DIRS} nor @code{AC_CONFIG_MACRO_DIR} is
declared there, the option immediately following the first @samp{-I}
from @code{ACLOCAL_AMFLAGS} in @file{Makefile.am} is used as a last
resort. If you don't want to declare the macro directory in any of
those places, then you can specify it in @file{bootstrap.conf} by
using the @code{macro_dir} variable.

@smallexample
macro_dir=acm4
@end smallexample


@cnindex package
@item package
This is automatically extracted by downcasing the first argument to
@code{AC_INIT} in @file{configure.ac}, though you can override it here
if you prefer.

@cnindex package_name
@item package_name
This is automatically extracted from the first argument to
@code{AC_INIT} in @file{configure.ac}, though you can override it here
if you prefer.

@cnindex package_version
@item package_version
This is automatically extracted from the second argument to
@code{AC_INIT} in @file{configure.ac}, though you can override it here
if you prefer.

@cnindex package_bugreport
@item package_bugreport
This is automatically extracted from the third argument to
@code{AC_INIT} in @file{configure.ac} if given, though you can override
it here if you prefer.


@cnindex doc_base
@cnindex gnulib_mk
@cnindex gnulib_name
@cnindex local_gl_path
@cnindex source_base
@cnindex tests_base
@item doc_base
@itemx gnulib_mk
@itemx gnulib_name
@itemx local_gl_path
@itemx source_base
@itemx tests_base
These are normally extracted from @file{gnulib-cache.m4}, regardless of
their values in @file{bootstrap.conf}.

When that file is not yet created, then @command{bootstrap} will
fall-back automatically to the gnulib defaults; unless you set
alternative values here in @file{bootstrap.conf}.

If you check @file{gnulib-cache.m4} into your repository, then these
values will be extracted automatically. @xref{Usage Patterns}, for more
details.


@cnindex gnulib_modules
@item gnulib_modules
The list of gnulib modules required at @command{gnulib-tool} time.

If you check @file{gnulib-cache.m4} into your repository, then this list
will be extracted automatically. @xref{Usage Patterns}, for more
details.


@cnindex gnulib_non_module_files
@item gnulib_non_module_files
Extra gnulib files that are not part of a gnulib module, but which
override files of the same name installed by other bootstrap tools, such
as @command{automake}.

@smallexample
gnulib_non_module_files="$gnulib_non_module_files"'
        doc/COPYINGv3
'
@end smallexample


@cnindex gnulib_path
@cnindex gnulib_url
@item gnulib_path
@itemx gnulib_url
Relative path to the local gnulib submodule, and url to the upstream
git repository for gnulib. These are only used if a new gnulib submodule
needs to be created, otherwise they are ignored and the values stored in
@file{.gitmodules} are used instead.

Normally, you can leave these untouched, and @command{bootstrap} will
correctly check out a gnulib submodule from the directory passed with
@option{--gnulib-srcdir}, or else from the upstream repository at GNU
savannah.


@cnindex gnulib_tool_options
@item gnulib_tool_options
Additional options to pass to @command{gnulib-tool} when it is called.

@smallexample
gnulib_tool_options='
        --no-changelog
        --libtool
'
@end smallexample


@cnindex gnulib_precious
@item gnulib_precious
Normally, @command{bootstrap} removes any macro-files that are not
included by @file{aclocal.m4} before it returns, except for files listed
in this variable which are always kept.

@smallexample
gnulib_precious='
        gnulib-cache.m4
'
@end smallexample


@cnindex min_cmd_len
@item min_cmd_len
When truncating long commands for display at runtime, always allow at
least this many characters before truncating.


@cnindex po_download_command_format
@item po_download_command_format
The command to download all @samp{.po} files for a specified domain into
a specified directory, where the first %s is filled in with the
@emph{domain name}, and the second with the @emph{destination
directory}.  Use @command{rsync}'s @option{-L} and @option{-r} options
because the latest @samp{/%s} directory and the @samp{.po} files within
are all symlinks.

@smallexample
po_download_command_format=\
"rsync --delete --exclude '*.s1' -Lrtvz \
'translationproject.org::tp/latest/%s/' '%s'"
@end smallexample

This variable is only interesting to projects with NLS support, and even
then, Usually, the default setting will be sufficient.


@cnindex extra_locale_categories
@item extra_locale_categories
Other locale categories that need message catalogs.  This variable is
only interesting to projects with NLS support.


@cnindex xgettext_options
@item xgettext_options
Additional @command{xgettext} options to use.  Gnulib might provide you
with an extensive list of additional options to append to this, but
gettext 0.16.1 and newer already appends those automaticaly, so you can
safely ignore the complaints from @command{gnulib-tool} as long as your
@file{configure.ac} declares @code{AM_GNU_GETTEXT_VERSION([0.16.1])}.

@smallexample
xgettext_options='
        --flag=_:1:pass-c-format
        --flag=N_:1:pass-c-format
'
@end smallexample

As with the previous two variables, you can safely ignore this one if
your project does not have NLS support.


@cnindex copyright_holder
@item copyright_holder
Package copyright holder for gettext files.  Defaults to @samp{FSF} if
unset.

@cnindex checkout_only_file
@item checkout_only_file
If you want @command{bootstrap} to abort if it is executed outside of
a version controlled tree, this variable must hold the name of some file
that is present only in a checked out tree, and is not in a distribution
tarball.

@smallexample
checkout_only_file=HACKING
@end smallexample

@cnindex copy
@item copy
If set to @samp{true}, then make copies when adding files to this
package, otherwise make symlinks by default. If set to @samp{true},
then the @option{--copy} option to @command{bootstrap} will have no
further effect.


@cnindex vc_ignore
@item vc_ignore
Set this to @samp{.cvsignore .gitignore} if you want both of those files
to be generated in directories such as @file{lib/}, @file{m4/}, and
@file{po/}, or set it to @samp{auto} to make @command{bootstrap} select
which to use based on which version control system (if any) is used in
the source directory.  Or set it to @samp{none} to disregard VCS ignore
files entirely.  Default is @samp{auto}.

@smallexample
vc_ignore='.cvsignore .gitignore'
@end smallexample

@end itemize


@node Require Variables
@subsection Require Variables

Many of the functions in @command{bootstrap} should not be executed more
than once, which is achieved by storing the name of that function in a
variable and then calling it with:

@smallexample
$require_gnulib_tool
@end smallexample

At this stage, the value of the variable is interpreted as a function
call by the shell, and the named function then runs.  Under normal
circumstances, functions that are called in this way always set their
associated variable name to simply @samp{:} so that subsequent
occurrences of, in this instance, @code{$require_gnulib_tool} have no
further effect.

That means you can easily skip any functions that are called like this
by unconditionally setting the require variable to @samp{:} in your
@file{bootstrap.conf}. So, for example, if your package makes no use of
@command{gnulib-tool}, you can add the following to your
@file{bootstrap.conf}:

@smallexample
require_gnulib_tool=:
@end smallexample

You should be aware, however, that the function calls managed by this
mechanism are designed to be called one time to ensure that some
resource is available for use by the rest of any function that uses a
@code{$require_some_resource} call.  Be careful to ensure that you
remove any code paths that try to use that resource if you have
effectively disabled it by setting its variable to @samp{:} early on.


@node Hook Functions
@subsection Hook Functions

Many of the key functions in @command{bootstrap} will run one or more hook
functions before they return.  Essentially, all that the entire script
does is to define a lot of functions (some of which will run hooks),
then source the contents of your @file{bootstrap.conf} customisations,
and then finally run the @code{func_bootstrap} function.  Read the
doc-comments above @code{func_bootstrap} in the @command{bootstrap} file,
as well as the functions that it calls to find where you can hook your
own functions, in order to be called during your customised execution of
@command{bootstrap}.

One of the trickier hook functions is set up to allow you to add
additional arguments to the option parser for @command{bootstrap} without
having to replace @code{func_parse_options} in its entirety:

@smallexample
my_silent_option ()
@{
    $debug_cmd

    case $1 in
      --silent|-s) opt_silent=:; shift ;;
    esac

    # return modified option list
    func_quote eval $@{1+"$@@"@}
    func_run_hooks_result=$func_quote_result
@}
func_add_hook func_parse_options my_silent_option
@end smallexample


@node Function Replacement
@subsection Function Replacement

In a few complex packages, you might find that some selection of
functions called during the normal execution of @command{bootstrap} are
wholly inappropriate for your project, where simply disabling
@code{$require_some_resource} functions and hooking in additional code
is not powerful enough to avoid or radically alter the parts of
@command{bootstrap} you do not want.

In that case you can simply write an entirely custom implementation of
whatever function(s) you want to replace inside your
@file{bootstrap.conf}, so that by the time @code{func_bootstrap} is
called at the end of @command{bootstrap}, your new implementation is
already in place.

@example
func_echo ()
@{
    # respect new --silent option
    $opt_silent || echo "$progname: $*"
@}
@end example


@node Usage Patterns
@section Usage Patterns

There are two ways to incorporate gnulib into your package, which are
both supported by the @command{bootstrap} script.  Be sure that everyone
working on your package is employing the same usage pattern, or things
will turn bad!

@menu
* Configuration all kept in @file{bootstrap.conf}
* Gnulib configuration stored in @file{gnulib-cache.m4}
@end menu


@node Configuration all kept in @file{bootstrap.conf}
@subsection Configuration all kept in @file{bootstrap.conf}

All the parameters for running @command{gnulib-tool} and other bootstrap-
time commands are maintained in @file{bootstrap.conf}. This is the
default usage pattern.

In order for this to work, when you wish to add or remove a gnulib
module from your package, amend the value of @var{gnulib_modules} in
@file{bootstrap.conf} (and similarly for any other parameters) and rerun
@command{bootstrap} to import everything anew.

To avoid things getting out of sync, you should never run
@command{gnulib-tool} directly.


@node Gnulib configuration stored in @file{gnulib-cache.m4}
@subsection Gnulib configuration stored in @file{gnulib-cache.m4}

To implement this usage pattern, leave the value of @var{gnulib_modules}
and the various @var{gl_xxx} variables empty in @file{bootstrap.conf}
and call @command{gnulib-tool --import ...} from your shell, checking
that @file{gnulib-cache.m4} reflects the values you wanted.  From now on
you can either call @command{gnulib-tool --update} or rerun
@command{bootstrap} whenever you want to resync the package modules with
your local gnulib checkout.

If you wish to add or remove a gnulib module from your package, call
@command{gnulib-tool --import-add ...} or @command{gnulib-tool --import-
remove} respectively.

@node Known Bugs
@section Known Bugs

@itemize @bullet
@item
gnulib-tool has no @option{--force} option, so sometimes symlinks are
left pointing to an old gnulib tree (even with @command{./bootstrap
--force}):

@smallexample
$ ./bootstrap --skip-git --gnulib-srcdir=../gnulib
$ ./bootstrap --gnulib-srcdir=../gnulib --force
@end smallexample

Note that now, plenty of symlinks still point to @file{../gnulib}
instead of having being retargeted to the submodule in @file{./gnulib}.
@end item
@end itemize
